home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Found / FWMemory / Sources / FWFixMem.cpp next >
Encoding:
Text File  |  1995-11-08  |  5.5 KB  |  188 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWMemMgr.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    (c) 1993, 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFound.hpp"
  11.  
  12. #ifndef   FWMEMMGR_H
  13. #include "FWMemMgr.h"
  14. #endif
  15.  
  16. #ifndef FWFIXMEM_H
  17. #include "FWFixMem.h"
  18. #endif
  19.  
  20. #ifndef FWDEBUG_H
  21. #include "FWDebug.h"
  22. #endif
  23.  
  24. #ifdef FW_BUILD_MAC
  25. #pragma segment FWMemory
  26. #endif
  27.  
  28. #if FW_LIB_EXPORT_PRAGMAS
  29. #pragma lib_export on
  30. #endif
  31.  
  32. //========================================================================================
  33. // STRUCT FW_SPrivFixedNode
  34. //========================================================================================
  35.  
  36. struct FW_SPrivFixedNode
  37. {
  38.     FW_SPrivFixedNode*    fNext;
  39.  
  40.     static    FW_SPrivFixedNode*    FromMemBlock(void* memblock);
  41. };
  42.  
  43. //----------------------------------------------------------------------------------------
  44. // FW_SPrivFixedNode::FromMemBlock
  45. //----------------------------------------------------------------------------------------
  46.  
  47. FW_SPrivFixedNode*    FW_SPrivFixedNode::FromMemBlock(void* memBlock)
  48. {
  49.     FW_SPrivFixedNode* node = (FW_SPrivFixedNode*) memBlock;
  50.     return node;
  51. }
  52.  
  53. //========================================================================================
  54. // STRUCT FW_SPrivFixedBlock
  55. //========================================================================================
  56.  
  57. struct FW_SPrivFixedBlock
  58. {
  59.     FW_SPrivFixedBlock*    fNext;
  60.     
  61.     static    FW_SPrivFixedBlock*    Allocate(short nNodeSize, short nNodes,
  62.                                     FW_SPrivFixedNode*& firstNode, FW_SPrivFixedNode*& lastNode);
  63.     static    void                Free(FW_SPrivFixedBlock* block);
  64. };
  65.  
  66. //----------------------------------------------------------------------------------------
  67. // FW_SPrivFixedBlock::Allocate
  68. //----------------------------------------------------------------------------------------
  69.  
  70. FW_SPrivFixedBlock*    FW_SPrivFixedBlock::Allocate(short nNodeSize, short nNodes,
  71.                                     FW_SPrivFixedNode*& firstNode, FW_SPrivFixedNode*& lastNode)
  72. {
  73.     FW_ASSERT(nNodeSize >= sizeof(FW_SPrivFixedNode));
  74.  
  75.     // Allocate the large memory block
  76.     FW_SPrivFixedBlock* block = (FW_SPrivFixedBlock*)
  77.         FW_CMemoryManager::AllocateBlock((unsigned long) nNodeSize * nNodes + sizeof(FW_SPrivFixedBlock));
  78.     void* blockData = block + 1;    
  79.  
  80.     // Set first and last pointers
  81.     firstNode = (FW_SPrivFixedNode*) blockData;
  82.     lastNode  = (FW_SPrivFixedNode*) (((char*) blockData) + nNodeSize * (nNodes - 1));
  83.  
  84.     // Slice and dice the block
  85.     lastNode->fNext = NULL;
  86.     FW_SPrivFixedNode* node = (FW_SPrivFixedNode*) blockData;
  87.     for (short n = 0; n < nNodes - 1; ++ n)
  88.     {
  89.         FW_SPrivFixedNode* next = (FW_SPrivFixedNode*) (((char*) node) + nNodeSize);
  90.         node->fNext = next;
  91.         node = next;
  92.     }
  93.     FW_ASSERT(node == lastNode);
  94.  
  95.     // Return the whole block
  96.     return block;
  97. }
  98.  
  99. //----------------------------------------------------------------------------------------
  100. // FW_SPrivFixedBlock::Free
  101. //----------------------------------------------------------------------------------------
  102.  
  103. void FW_SPrivFixedBlock::Free(FW_SPrivFixedBlock* block)
  104. {
  105.     FW_CMemoryManager::FreeBlock(block);
  106. }
  107.  
  108. //========================================================================================
  109. // CLASS FW_CFixedAllocator
  110. //========================================================================================
  111.  
  112. const int kNodesPerBlock    = 100;
  113.  
  114. //----------------------------------------------------------------------------------------
  115. // FW_CFixedAllocator::FW_CFixedAllocator
  116. //----------------------------------------------------------------------------------------
  117.  
  118. FW_CFixedAllocator::FW_CFixedAllocator(short allocSize) :
  119.     fAllocCount(0),
  120.     fAllocSize((allocSize + 3) & ~3),        // Round the size up to a multiple of 4 bytes
  121.     fFreeList(NULL),
  122.     fBlockList(NULL)
  123. {
  124. }
  125.  
  126. //----------------------------------------------------------------------------------------
  127. // FW_CFixedAllocator::~FW_CFixedAllocator
  128. //----------------------------------------------------------------------------------------
  129.  
  130. FW_CFixedAllocator::~FW_CFixedAllocator()
  131. {
  132.     FW_ASSERT(fAllocCount == 0);
  133.     FW_ASSERT(fFreeList == NULL);
  134.     FW_ASSERT(fBlockList == NULL);
  135. }
  136.  
  137. //----------------------------------------------------------------------------------------
  138. // FW_CFixedAllocator::Allocate
  139. //----------------------------------------------------------------------------------------
  140.  
  141. void* FW_CFixedAllocator::Allocate()
  142. {
  143.     // Make sure there is something on our free list
  144.     if (fFreeList == NULL)
  145.     {
  146.         FW_SPrivFixedNode *firstNode, *lastNode;
  147.         FW_SPrivFixedBlock *newBlock =
  148.             FW_SPrivFixedBlock::Allocate(fAllocSize, kNodesPerBlock, firstNode, lastNode);
  149.  
  150.         lastNode->fNext = fFreeList;
  151.         fFreeList = firstNode;
  152.  
  153.         newBlock->fNext = fBlockList;
  154.         fBlockList = newBlock;
  155.     }
  156.     
  157.     // Take the first node from the free list
  158.     void* newNode = fFreeList;
  159.     fFreeList = fFreeList->fNext;
  160.     ++ fAllocCount;
  161.     return newNode;
  162. }
  163.  
  164. //----------------------------------------------------------------------------------------
  165. // FW_CFixedAllocator::Free
  166. //----------------------------------------------------------------------------------------
  167.  
  168. void FW_CFixedAllocator::Free(void* block)
  169. {
  170.     // Return the block to the free node list
  171.     FW_SPrivFixedNode* node = FW_SPrivFixedNode::FromMemBlock(block);
  172.     node->fNext = fFreeList;
  173.     fFreeList = node;
  174.  
  175.     // If no more nodes, free the whole list
  176.     if (-- fAllocCount == 0)
  177.     {
  178.         while (fBlockList != NULL)
  179.         {
  180.             FW_SPrivFixedBlock*    next = fBlockList->fNext;
  181.             FW_SPrivFixedBlock::Free(fBlockList);
  182.             fBlockList = next;
  183.         }
  184.         
  185.         fFreeList = NULL;
  186.     }
  187. }
  188.